{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from sklearn import datasets\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.model_selection import ShuffleSplit\n",
    "import pandas as pd\n",
    "from sklearn.preprocessing import LabelEncoder # poderia ser LabelBinarizer\n",
    "from sklearn.preprocessing import MinMaxScaler\n",
    "from sklearn.model_selection import GridSearchCV\n",
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "from matplotlib import pyplot as plt\n",
    "from sklearn.metrics import classification_report\n",
    "%matplotlib inline\n",
    "plt.style.use('ggplot')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Modelo "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "class KNNClassifier(object):\n",
    "    def __init__(self, n = 1):\n",
    "        self.X_train = None\n",
    "        self.y_train = None\n",
    "        self.n = n\n",
    "\n",
    "    def closest(self, row):\n",
    "        \"\"\"\n",
    "        Retorna a classe respondente ao ponto mais próximo do dataset de treino.\\\n",
    "        É um exemplo de implementação do kNN com k=1.\n",
    "        \"\"\"\n",
    "    \n",
    "        # calcula as distâncias(norma L2) entre row e os pontos no dataset\n",
    "        distances = np.linalg.norm(self.X_train - row, axis=1)\n",
    "        # calcula os índices dos n pontos com menor distância para row\n",
    "        smallest_n_ix = np.argpartition(distances, self.n)[:self.n]\n",
    "        # calcula os labels dos pontos do passo anterior\n",
    "        labels = self.y_train[smallest_n_ix]\n",
    "        \n",
    "        # retorna o label com a maior quantidade de ocorrências em labels\n",
    "        return np.bincount(labels).argmax()\n",
    "\n",
    "    def fit(self, training_data, training_labels):\n",
    "        self.X_train = training_data\n",
    "        self.y_train = training_labels\n",
    "        \n",
    "        return self\n",
    "\n",
    "    def predict(self, to_classify):\n",
    "        predictions = []\n",
    "        for row in to_classify:\n",
    "            label = self.closest(row)\n",
    "            predictions.append(label)\n",
    "        return predictions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Titanic Dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>PassengerId</th>\n",
       "      <th>Survived</th>\n",
       "      <th>Pclass</th>\n",
       "      <th>Name</th>\n",
       "      <th>Sex</th>\n",
       "      <th>Age</th>\n",
       "      <th>SibSp</th>\n",
       "      <th>Parch</th>\n",
       "      <th>Ticket</th>\n",
       "      <th>Fare</th>\n",
       "      <th>Cabin</th>\n",
       "      <th>Embarked</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>3</td>\n",
       "      <td>Braund, Mr. Owen Harris</td>\n",
       "      <td>male</td>\n",
       "      <td>22.0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>A/5 21171</td>\n",
       "      <td>7.2500</td>\n",
       "      <td>NaN</td>\n",
       "      <td>S</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>Cumings, Mrs. John Bradley (Florence Briggs Th...</td>\n",
       "      <td>female</td>\n",
       "      <td>38.0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>PC 17599</td>\n",
       "      <td>71.2833</td>\n",
       "      <td>C85</td>\n",
       "      <td>C</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>1</td>\n",
       "      <td>3</td>\n",
       "      <td>Heikkinen, Miss. Laina</td>\n",
       "      <td>female</td>\n",
       "      <td>26.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>STON/O2. 3101282</td>\n",
       "      <td>7.9250</td>\n",
       "      <td>NaN</td>\n",
       "      <td>S</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>Futrelle, Mrs. Jacques Heath (Lily May Peel)</td>\n",
       "      <td>female</td>\n",
       "      <td>35.0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>113803</td>\n",
       "      <td>53.1000</td>\n",
       "      <td>C123</td>\n",
       "      <td>S</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>0</td>\n",
       "      <td>3</td>\n",
       "      <td>Allen, Mr. William Henry</td>\n",
       "      <td>male</td>\n",
       "      <td>35.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>373450</td>\n",
       "      <td>8.0500</td>\n",
       "      <td>NaN</td>\n",
       "      <td>S</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   PassengerId  Survived  Pclass  \\\n",
       "0            1         0       3   \n",
       "1            2         1       1   \n",
       "2            3         1       3   \n",
       "3            4         1       1   \n",
       "4            5         0       3   \n",
       "\n",
       "                                                Name     Sex   Age  SibSp  \\\n",
       "0                            Braund, Mr. Owen Harris    male  22.0      1   \n",
       "1  Cumings, Mrs. John Bradley (Florence Briggs Th...  female  38.0      1   \n",
       "2                             Heikkinen, Miss. Laina  female  26.0      0   \n",
       "3       Futrelle, Mrs. Jacques Heath (Lily May Peel)  female  35.0      1   \n",
       "4                           Allen, Mr. William Henry    male  35.0      0   \n",
       "\n",
       "   Parch            Ticket     Fare Cabin Embarked  \n",
       "0      0         A/5 21171   7.2500   NaN        S  \n",
       "1      0          PC 17599  71.2833   C85        C  \n",
       "2      0  STON/O2. 3101282   7.9250   NaN        S  \n",
       "3      0            113803  53.1000  C123        S  \n",
       "4      0            373450   8.0500   NaN        S  "
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = pd.read_csv(\"https://github.com/abevieiramota/kaggle-titanic/raw/master/data/train.csv\")\n",
    "\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>PassengerId</th>\n",
       "      <th>Survived</th>\n",
       "      <th>Pclass</th>\n",
       "      <th>Age</th>\n",
       "      <th>SibSp</th>\n",
       "      <th>Parch</th>\n",
       "      <th>Fare</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>count</th>\n",
       "      <td>891.000000</td>\n",
       "      <td>891.000000</td>\n",
       "      <td>891.000000</td>\n",
       "      <td>714.000000</td>\n",
       "      <td>891.000000</td>\n",
       "      <td>891.000000</td>\n",
       "      <td>891.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>mean</th>\n",
       "      <td>446.000000</td>\n",
       "      <td>0.383838</td>\n",
       "      <td>2.308642</td>\n",
       "      <td>29.699118</td>\n",
       "      <td>0.523008</td>\n",
       "      <td>0.381594</td>\n",
       "      <td>32.204208</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>std</th>\n",
       "      <td>257.353842</td>\n",
       "      <td>0.486592</td>\n",
       "      <td>0.836071</td>\n",
       "      <td>14.526497</td>\n",
       "      <td>1.102743</td>\n",
       "      <td>0.806057</td>\n",
       "      <td>49.693429</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>min</th>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.420000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25%</th>\n",
       "      <td>223.500000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>2.000000</td>\n",
       "      <td>20.125000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>7.910400</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>50%</th>\n",
       "      <td>446.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>3.000000</td>\n",
       "      <td>28.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>14.454200</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>75%</th>\n",
       "      <td>668.500000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>3.000000</td>\n",
       "      <td>38.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>31.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>max</th>\n",
       "      <td>891.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>3.000000</td>\n",
       "      <td>80.000000</td>\n",
       "      <td>8.000000</td>\n",
       "      <td>6.000000</td>\n",
       "      <td>512.329200</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       PassengerId    Survived      Pclass         Age       SibSp  \\\n",
       "count   891.000000  891.000000  891.000000  714.000000  891.000000   \n",
       "mean    446.000000    0.383838    2.308642   29.699118    0.523008   \n",
       "std     257.353842    0.486592    0.836071   14.526497    1.102743   \n",
       "min       1.000000    0.000000    1.000000    0.420000    0.000000   \n",
       "25%     223.500000    0.000000    2.000000   20.125000    0.000000   \n",
       "50%     446.000000    0.000000    3.000000   28.000000    0.000000   \n",
       "75%     668.500000    1.000000    3.000000   38.000000    1.000000   \n",
       "max     891.000000    1.000000    3.000000   80.000000    8.000000   \n",
       "\n",
       "            Parch        Fare  \n",
       "count  891.000000  891.000000  \n",
       "mean     0.381594   32.204208  \n",
       "std      0.806057   49.693429  \n",
       "min      0.000000    0.000000  \n",
       "25%      0.000000    7.910400  \n",
       "50%      0.000000   14.454200  \n",
       "75%      0.000000   31.000000  \n",
       "max      6.000000  512.329200  "
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.describe()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# converte valores categóricos em inteiros com range [0, n_categorias - 1]\n",
    "sex_encoder = LabelEncoder().fit(df.Sex)\n",
    "df['Sex_encoded'] = sex_encoder.transform(df.Sex)\n",
    "\n",
    "cabin_encoder = LabelEncoder().fit(df.Cabin.fillna(\"None\"))\n",
    "# atribui None aos valores faltantes em Cabin\n",
    "df[\"Cabin_encoded\"] = cabin_encoder.transform(df.Cabin.fillna(\"None\"))\n",
    "\n",
    "embarked_encoder = LabelEncoder().fit(df.Embarked.fillna(\"None\"))\n",
    "# atribui None aos valores faltantes em Embarked\n",
    "df[\"Embarked_encoded\"] = embarked_encoder.transform(df.Embarked.fillna(\"None\"))\n",
    "\n",
    "# atribui a média de Age aos valores faltantes em Age\n",
    "df['Age_imputed'] = df.Age.fillna(df.Age.mean())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# colunas selecionadas para treino\n",
    "columns = ['Pclass', 'Sex_encoded', 'Cabin_encoded', 'Embarked_encoded', 'Age_imputed', 'SibSp', 'Parch']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Pclass</th>\n",
       "      <th>Sex_encoded</th>\n",
       "      <th>Cabin_encoded</th>\n",
       "      <th>Embarked_encoded</th>\n",
       "      <th>Age_imputed</th>\n",
       "      <th>SibSp</th>\n",
       "      <th>Parch</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>Pclass</th>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.131900</td>\n",
       "      <td>0.682176</td>\n",
       "      <td>0.197493</td>\n",
       "      <td>-0.331339</td>\n",
       "      <td>0.083081</td>\n",
       "      <td>0.018443</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Sex_encoded</th>\n",
       "      <td>0.131900</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.095991</td>\n",
       "      <td>0.106395</td>\n",
       "      <td>0.084153</td>\n",
       "      <td>-0.114631</td>\n",
       "      <td>-0.245489</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Cabin_encoded</th>\n",
       "      <td>0.682176</td>\n",
       "      <td>0.095991</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.232192</td>\n",
       "      <td>-0.234912</td>\n",
       "      <td>0.043525</td>\n",
       "      <td>-0.028179</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Embarked_encoded</th>\n",
       "      <td>0.197493</td>\n",
       "      <td>0.106395</td>\n",
       "      <td>0.232192</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>-0.034883</td>\n",
       "      <td>0.068043</td>\n",
       "      <td>0.032517</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Age_imputed</th>\n",
       "      <td>-0.331339</td>\n",
       "      <td>0.084153</td>\n",
       "      <td>-0.234912</td>\n",
       "      <td>-0.034883</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>-0.232625</td>\n",
       "      <td>-0.179191</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>SibSp</th>\n",
       "      <td>0.083081</td>\n",
       "      <td>-0.114631</td>\n",
       "      <td>0.043525</td>\n",
       "      <td>0.068043</td>\n",
       "      <td>-0.232625</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.414838</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Parch</th>\n",
       "      <td>0.018443</td>\n",
       "      <td>-0.245489</td>\n",
       "      <td>-0.028179</td>\n",
       "      <td>0.032517</td>\n",
       "      <td>-0.179191</td>\n",
       "      <td>0.414838</td>\n",
       "      <td>1.000000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                    Pclass  Sex_encoded  Cabin_encoded  Embarked_encoded  \\\n",
       "Pclass            1.000000     0.131900       0.682176          0.197493   \n",
       "Sex_encoded       0.131900     1.000000       0.095991          0.106395   \n",
       "Cabin_encoded     0.682176     0.095991       1.000000          0.232192   \n",
       "Embarked_encoded  0.197493     0.106395       0.232192          1.000000   \n",
       "Age_imputed      -0.331339     0.084153      -0.234912         -0.034883   \n",
       "SibSp             0.083081    -0.114631       0.043525          0.068043   \n",
       "Parch             0.018443    -0.245489      -0.028179          0.032517   \n",
       "\n",
       "                  Age_imputed     SibSp     Parch  \n",
       "Pclass              -0.331339  0.083081  0.018443  \n",
       "Sex_encoded          0.084153 -0.114631 -0.245489  \n",
       "Cabin_encoded       -0.234912  0.043525 -0.028179  \n",
       "Embarked_encoded    -0.034883  0.068043  0.032517  \n",
       "Age_imputed          1.000000 -0.232625 -0.179191  \n",
       "SibSp               -0.232625  1.000000  0.414838  \n",
       "Parch               -0.179191  0.414838  1.000000  "
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df[columns].corr()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# remove Cabin_encoded, dada a alta correlação com Pclass\n",
    "columns.remove('Cabin_encoded')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# escala linearmente as colunas para o range [0, 1] e gera o dataset a ser utilizada\n",
    "#    no treinamento do modelo\n",
    "X = MinMaxScaler().fit_transform(df[columns])\n",
    "# gera o vetor y, com o atributo da classificação\n",
    "y = df.Survived.values "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# particiona o dataset em\n",
    "#    dataset de treino, a partir do qual o modelo será treinado\n",
    "#    dataset de validação, a partir do qual o modelo treinado será avaliado\n",
    "X_train, X_valid, y_train, y_valid = train_test_split(X, y, test_size=.1, random_state=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "GridSearchCV(cv=ShuffleSplit(n_splits=1, random_state=0, test_size=0.25, train_size=None),\n",
       "       error_score='raise',\n",
       "       estimator=KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',\n",
       "           metric_params=None, n_jobs=1, n_neighbors=5, p=2,\n",
       "           weights='uniform'),\n",
       "       fit_params={}, iid=True, n_jobs=1,\n",
       "       param_grid={'n_neighbors': array([ 1,  5,  9, 13, 17, 21, 25, 29])},\n",
       "       pre_dispatch='2*n_jobs', refit=True, return_train_score=True,\n",
       "       scoring=None, verbose=0)"
      ]
     },
     "execution_count": 68,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "knn = KNeighborsClassifier()\n",
    "# objeto responsável por gerar uma partição(n_splits=1) aleatória\n",
    "#    com 75% dos dados para treino e 25% dos dados para teste(test_size=.25)\n",
    "#    fixa random_state=0 para permitir que o resultado seja reproduzido\n",
    "ss = ShuffleSplit(test_size=.25, n_splits=1, random_state=0)\n",
    "\n",
    "n_neighbors = np.arange(1, 30, 4)\n",
    "param_grid = {'n_neighbors': n_neighbors}\n",
    "\n",
    "# classe responsável por treinar o modelo com todas as combinações\n",
    "#   de parâmetros em param_grid, sobre todas as partições geradas pelo ShuffleSplit\n",
    "cv = GridSearchCV(knn, param_grid, cv=ss)\n",
    "# executa o treinamento\n",
    "cv.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.text.Text at 0x217ec0e6b38>"
      ]
     },
     "execution_count": 75,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\nrkJggg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x217ec12c978>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(10, 6))\n",
    "plt.plot(n_neighbors, cv.cv_results_['mean_train_score'])\n",
    "plt.plot(n_neighbors, cv.cv_results_['mean_test_score'])\n",
    "plt.legend(['treino', 'teste'])\n",
    "plt.title(\"Accuracy\")\n",
    "plt.xlabel(\"N neighbors\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'n_neighbors': 9}"
      ]
     },
     "execution_count": 78,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "cv.best_params_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',\n",
       "           metric_params=None, n_jobs=1, n_neighbors=9, p=2,\n",
       "           weights='uniform')"
      ]
     },
     "execution_count": 80,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# seleciona o modelo com melhor accuracy sobre o dataset de teste\n",
    "#    de acordo com as partições geradas pelo ShuffleSplit\n",
    "best_fit = cv.best_estimator_\n",
    "# treina com todo o dataset de treino\n",
    "best_fit.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "             precision    recall  f1-score   support\n",
      "\n",
      "          0       0.87      0.72      0.79        64\n",
      "          1       0.51      0.73      0.60        26\n",
      "\n",
      "avg / total       0.77      0.72      0.73        90\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# avalia seu desempenho sobre o dataset de validação(não foi utilizado no treinamento)\n",
    "print(classification_report(best_fit.predict(X_valid), y_valid))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
